<script setup lang="ts">
import { reactive, ref, watch } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import type { ConfigItem, ConfigUpdatePayload } from "@/api/system/config";
import { message } from "@/utils/message";

interface Props {
  item: ConfigItem;
  onSubmit: (payload: ConfigUpdatePayload) => Promise<void>;
}

const props = defineProps<Props>();

const innerFormRef = ref<FormInstance>();

const formModel = reactive({
  config_value: "",
  status: 1,
  description: ""
});

const rules: FormRules<typeof formModel> = {
  config_value: [{ required: true, message: "请填写配置值", trigger: "blur" }]
};

const formatValue = (item: ConfigItem) => {
  if (item.value_type === "json") {
    try {
      return JSON.stringify(item.config_value, null, 2);
    } catch {
      return String(item.config_value ?? "");
    }
  }
  if (typeof item.config_value === "boolean") {
    return item.config_value ? "true" : "false";
  }
  return String(item.config_value ?? "");
};

const applyItem = (item: ConfigItem) => {
  formModel.config_value = formatValue(item);
  formModel.status = Number(item.status ?? 1) as 0 | 1;
  formModel.description = item.description ?? "";
};

watch(
  () => props.item,
  item => {
    if (item) {
      applyItem(item);
    }
  },
  { immediate: true }
);

const parseValue = () => {
  const item = props.item;
  const raw = formModel.config_value;
  switch (item.value_type) {
    case "int":
      if (raw === "") throw new Error("请输入数值");
      if (Number.isNaN(Number(raw))) throw new Error("数值格式不正确");
      return Number(raw);
    case "bool":
      return raw === "true" || raw === "1" || raw === "on";
    case "json":
      try {
        return raw ? JSON.parse(raw) : {};
      } catch (error) {
        throw new Error("JSON 格式不正确");
      }
    case "decimal":
    case "float":
      if (raw === "") throw new Error("请输入数值");
      if (Number.isNaN(Number(raw))) throw new Error("数值格式不正确");
      return Number(raw);
    default:
      return raw;
  }
};

const submitForm = async () => {
  try {
    await innerFormRef.value?.validate();
  } catch {
    return false;
  }

  let parsed: unknown;
  try {
    parsed = parseValue();
  } catch (error: any) {
    message(error?.message ?? "配置值格式不正确", { type: "error" });
    return false;
  }

  try {
    await props.onSubmit({
      config_value: parsed,
      status: formModel.status,
      description: formModel.description
    });
    return true;
  } catch {
    return false;
  }
};

defineExpose({ submitForm });
</script>

<template>
  <el-form
    ref="innerFormRef"
    :model="formModel"
    :rules="rules"
    label-width="100px"
    status-icon
  >
    <el-form-item label="配置值" prop="config_value">
      <el-input
        v-model="formModel.config_value"
        type="textarea"
        :rows="6"
        placeholder="请输入配置值"
        show-word-limit
      />
    </el-form-item>
    <el-form-item label="状态" prop="status">
      <el-switch
        v-model="formModel.status"
        :inactive-value="0"
        :active-value="1"
      />
    </el-form-item>
    <el-form-item label="描述">
      <el-input
        v-model="formModel.description"
        type="textarea"
        :rows="3"
        maxlength="200"
        show-word-limit
        placeholder="配置用途或修改说明"
      />
    </el-form-item>
  </el-form>
</template>
